 /* 
  * Copyright (C) 2012 maxim 
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  * USA
  */

#include "tests.h"

#include "user_threads.h"
#include "user_mutex.h"

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

static uthread_mutex_t mutex1;
static uthread_mutex_t mutex2;

/* Creates a circular thread wait using mutex
 * Its almost a deadlock, but since thread 0 is running it can cancel both threads */


static int thread1(void* arg)
{
	uthread_mutex_lock(mutex1);
	uthread_yield();
	uthread_mutex_lock(mutex2);
	return 1;

}

static int thread2(void* arg)
{
	uthread_mutex_lock(mutex2);
	uthread_mutex_lock(mutex1);
	return 2;
}


void test6()
{
	msg("\nRunning test #6...");
	int ret;

	assert(uthread_mutex_init(&mutex1) == MUTEX_SUCCESS);
	assert(uthread_mutex_init(&mutex2) == MUTEX_SUCCESS);

	assert(uthread_create(thread1, NULL, 1) == 1);
	assert(uthread_create(thread2, NULL, 1) == 2);
	uthread_yield();
	uthread_yield();


	assert(uthread_cancel(1) == UTHREAD_SUCCESS);
	assert(uthread_cancel(2) == UTHREAD_SUCCESS);

	assert (uthread_join(1, &ret) == UTHREAD_SUCCESS);
	assert (ret == UTHREAD_CANCELLED);
	assert (uthread_join(2, &ret) == UTHREAD_SUCCESS);
	assert (ret == UTHREAD_CANCELLED);

	assert(uthread_cancel(1) == UTHREAD_INVALID);
	assert(uthread_cancel(2) == UTHREAD_INVALID);

	uthread_mutex_destroy(mutex1);
	/* don't destroy mutex2 on purpose... just in case*/
}
